package com.bigflexlib.core.async
{
	import com.bigflexlib.core.markers.IIncomplete;
	
	import flash.net.URLLoader;
	
	import mx.rpc.AsyncToken;
	
	/**
	 * 
	 * There are many async strategies throughout flex
	 * Events, ItemPendingErrors, AsyncTokens...
	 * 
	 * And there are different lifecycles.
	 * 
	 * The goal of this module is to create a common abstraction
	 * and define a consistent lifecycle.
	 * 
	 * Each AsyncWrapper lives for only one request.
	 * 
	 * 
	 * themes for the whole picture ( async and coercion )
	 * - unify async dialects ( concurrent, features, etc. this class is an early attempt )
	 * - create a new datatype
	 * -- can be deferred
	 * -- can be coerced
	 * -- cardinality: 1 or many
	 * --- single ( resource )
	 * --- multiple ( resource collections )
	 * ---- paging
	 * 
	 * Resource, ResourceCollections should be native-ish
	 * 
	 * SNORQ single node restriction query is a valid representation for a ResourceCollection
	 * If a function returns one, it is return, in fact, a Re$ourceCollection
	 * 
	 * 
	 * @author aldo.bucchi@univrz.com
	 * 
	 */	
	public class AsyncWrapper extends AsyncToken implements IIncomplete
	{
		

		private var _target:*;
		public function get target( ):*
		{
			return _target;
		}
		
		
		public function AsyncWrapper( target:* )
		{
			_target = target;
		}
		
		protected function informResult( result:*, extra:*=undefined ):void
		{
			try {
				resultFunc( result );
			} catch ( e:ArgumentError ) {
				resultFunc( result, extra );
			}		
		}				
		protected function informFault( fault:*, extra:*=undefined ):void
		{
			try {
				faultFunc( fault );
			} catch ( e:ArgumentError ) {
				faultFunc( fault, extra );
			}			
		}
		
		private var resultFunc:Function;
		private var faultFunc:Function;
		
		/**
		 * 
		 * // AsyncToken2 - responders, cancel( )
		 * 
		 * @param target
		 * @param resultFunc
		 * @param faultFunc
		 * @return 
		 * 
		 */		
		public static function i( target:*, resultFunc:Function=null, faultFunc:Function=null ):AsyncWrapper
		{
			var aw:AsyncWrapper = forTarget( target );
			aw.resultFunc = resultFunc;
			aw.faultFunc = faultFunc;
			return aw;		
		}
		
		private static function forTarget( target:* ):AsyncWrapper
		{
			if ( target is AsyncWrapper )
				return target;
				
			if ( target is URLLoader )
				return new URLLoaderAsyncWrapper( target );			

//			if ( target is AsyncToken )
//								
//			if ( target is ItemPendingError )
//			
//			if ( target is IEventDispatcher )

			return null;
		}
		
		
	}
	
}